/*
 * iot.c
 *
 *  Created on: Jun 21, 2022
 *      Author: MrYe1
 */

#include "tos_k.h"
#include "esp8266_tencent_firmware.h"
#include "tencent_firmware_module_wrapper.h"
#include "string.h"
#include "cJSON.h"
#include "core_riscv.h"

#define PRODUCT_ID              "EIW3XY4YVS"
#define DEVICE_NAME             "sw_01"
#define DEVICE_KEY              "ZxpnMYHcOAFZeCb8FMql7A=="

#define REPORT_DATA_TEMPLATE    "{\\\"method\\\":\\\"report\\\"\\,\\\"clientToken\\\":\\\"00000001\\\"\\,\\\"params\\\":{\\\"brightness\\\":%d\\,\\\"name\\\":\\\"bedroom\\\"}}"
#define EVENT_DATA_TEMPLATE  "{\\\"method\\\":\\\"report\\\"\\,\\\"clientToken\\\":\\\"00000001\\\"\\,\\\"params\\\":{\\\"brightness\\\":%d}}"
char msg_to_switch_ON  = 1;
char msg_to_switch_OFF = -1;
extern k_msg_q_t msg_q;
extern uint32_t g_sw_status;
extern uint32_t g_sw_status_pst;

k_event_t report_result_event;
k_event_flag_t report_success = 1<<0;
k_event_flag_t report_fail    = 1<<1;
void default_message_handler(mqtt_message_t* msg)
{
    char* ret = 0;
    int len = 0;
    cJSON* cjson_root   = NULL;
    cJSON* jmethod   = NULL;
    char* method = NULL;
    cJSON* jparams   = NULL;
    cJSON* jbrightness   = NULL;
    int brightness = 0;
    
    k_event_flag_t event_flag = report_fail;

    printf("callback:\r\n");
    printf("---------------------------------------------------------\r\n");
    printf("\ttopic:%s\r\n", msg->topic);
    printf("\tpayload:%s\r\n", msg->payload);
    // ret = strstr(msg->topic, "$thing/down/property/EIW3XY4YVS/sw_01");
    printf("---------------------------------------------------------\r\n");
    len = strlen(msg->payload);
//    printf("msg->payload[len-1]:%c\n", msg->payload[len-1]);
    if (len <= sizeof (msg->payload) && msg->payload[len-1] == '"')
        msg->payload[len-1] = '\0';

    cjson_root = cJSON_Parse((char*)(msg->payload +1));
    if (cjson_root == NULL) {
        printf("report reply message parser fail\r\n");
        event_flag = report_fail;
        goto exit;
    }

    jmethod = cJSON_GetObjectItem(cjson_root, "method");
    method = cJSON_GetStringValue(jmethod);

    jparams = cJSON_GetObjectItem(cjson_root, "params");
    jbrightness = cJSON_GetObjectItem(jparams, "brightness");
    brightness = jbrightness->valueint;
    if (jmethod == NULL || method == NULL ||
        jparams == NULL || jbrightness == NULL) 
    {
        printf("report reply status parser fail:%X\t%X\t%X\t%X\t%X\t\r\n",
            cjson_root, jmethod, method, jparams, jbrightness);
        event_flag = report_fail;
        goto exit;
    }

    if (strstr(method, "control") == NULL)
    {
        printf("method:%s\r\n", method);
        event_flag = report_fail;
        goto exit;
    }

    g_sw_status = brightness & 0x07;
    printf("g_sw_status:%d\n", g_sw_status);

exit:
//    cJSON_Delete(jbrightness);
//    cJSON_Delete(jparams);
//    cJSON_Delete(jmethod);
    cJSON_Delete(cjson_root);
    cjson_root = NULL;
    cjson_root   = NULL;
    jmethod   = NULL;
    method = NULL;
    jparams   = NULL;
    jbrightness   = NULL;
    // tos_event_post(&report_result_event, event_flag);
    return;
}

char payload[256] = {0};
static char event_topic_name[TOPIC_NAME_MAX_SIZE] = {0};
static char report_reply_topic_name[TOPIC_NAME_MAX_SIZE] = {0};

void mqtt_task_entry(void)
{
    int ret = 0;
    int size = 0;
    int lightness = 0;
    mqtt_state_t state;

    char *product_id = PRODUCT_ID;
    char *device_name = DEVICE_NAME;
    char *key = DEVICE_KEY;

    device_info_t dev_info;
    memset(&dev_info, 0, sizeof(device_info_t));

    /**
     * Please Choose your AT Port first, default is HAL_UART_2(USART2)
    */
    ret = esp8266_tencent_firmware_sal_init(HAL_UART_PORT_2);

    if (ret < 0) {
        printf("esp8266 tencent firmware sal init fail, ret is %d\r\n", ret);
    }

    esp8266_tencent_firmware_join_ap("YE_S10", "87654321");

    strncpy(dev_info.product_id, product_id, PRODUCT_ID_MAX_SIZE);
    strncpy(dev_info.device_name, device_name, DEVICE_NAME_MAX_SIZE);
    strncpy(dev_info.device_serc, key, DEVICE_SERC_MAX_SIZE);
    tos_tf_module_info_set(&dev_info, TLS_MODE_PSK);

    mqtt_param_t init_params = DEFAULT_MQTT_PARAMS;
    if (tos_tf_module_mqtt_conn(init_params) != 0) {
        printf("module mqtt conn fail\n");
    } else {
        printf("module mqtt conn success\n");
    }

    if (tos_tf_module_mqtt_state_get(&state) != -1) {
        printf("MQTT: %s\n", state == MQTT_STATE_CONNECTED ? "CONNECTED" : "DISCONNECTED");
    }

    size = snprintf(report_reply_topic_name, TOPIC_NAME_MAX_SIZE, "$thing/down/property/%s/%s", product_id, device_name);

    if (size < 0 || size > sizeof(report_reply_topic_name) - 1) {
        printf("sub topic content length not enough! content size:%d  buf size:%d", size, (int)sizeof(report_reply_topic_name));
    }
    if (tos_tf_module_mqtt_sub(report_reply_topic_name, QOS0, default_message_handler) != 0) {
        printf("module mqtt sub fail\n");
    } else {
        printf("module mqtt sub success\n");
    }

    memset(event_topic_name, 0, sizeof(event_topic_name));
    size = snprintf(event_topic_name, TOPIC_NAME_MAX_SIZE, "$thing/up/event/%s/%s", product_id, device_name);

    if (size < 0 || size > sizeof(event_topic_name) - 1) {
        printf("pub topic content length not enough! content size:%d  buf size:%d", size, (int)sizeof(event_topic_name));
    }

    while (1) {
        tos_sleep_ms(5000);

        /* use AT+PUB AT command */
        memset(payload, 0, sizeof(payload));
        snprintf(payload, sizeof(payload), EVENT_DATA_TEMPLATE, g_sw_status_pst & 0x0F);

        printf("pub payload:%s\n", payload);
        if (tos_tf_module_mqtt_pub(event_topic_name, QOS0, payload) != 0)
        {
            printf("module mqtt pub fail\n");
            break;
        }
        else
        {
            printf("module mqtt pub success\n");
        }
    }
}
